package judesart.app.client.ui.admin.profile;

import java.util.List;

import judesart.app.client.controller.ExhibitionController;
import judesart.app.client.controller.ExhibitionControllerAsync;
import judesart.app.client.widget.TopInfo;
import judesart.app.domain.Exhibition;
import judesart.app.domain.ExhibitionVideo;
import judesart.app.shared.UploadToken;
import pl.rmalinowski.gwt2swf.client.ui.SWFWidget;

import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.widget.Composite;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;

public class ExhibitionVideosPanel extends Composite {

    private final ExhibitionControllerAsync service = ExhibitionController.Util.getInstance();
    private final ExhibitionDetailPanel parent;
    private final LayoutContainer layoutContainer;
    private final FormPanel form;
    private final Hidden token;
    private final VerticalPanel videosPanel;
    private final TextField<String> videoId;
    private final VerticalPanel addVideoPanel;
    private final Anchor addNewVideoLink;

    public ExhibitionVideosPanel(ExhibitionDetailPanel parent) {
        this.parent = parent;

        layoutContainer = new LayoutContainer();
        layoutContainer.setSize(798, 450);
        layoutContainer.setBorders(false);
        layoutContainer.setScrollMode(Scroll.AUTO);

        videosPanel = new VerticalPanel();
        layoutContainer.add(videosPanel);
        refresh();

        addVideoPanel = new VerticalPanel();
        addVideoPanel.setVisible(false);
        form = new FormPanel();
        form.setMethod(FormPanel.METHOD_POST);
        form.setEncoding(FormPanel.ENCODING_MULTIPART);
        VerticalPanel panel = new VerticalPanel();
        form.setWidget(panel);
        FileUpload upload = new FileUpload();
        upload.setName("file");
        panel.add(upload);
        token = new Hidden("token", "token_value");
        panel.add(token);
        panel.add(new Button("Upload Video", new ClickHandler() {

            public void onClick(ClickEvent event) {
                form.submit();
            }
        }));
        form.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
            public void onSubmitComplete(SubmitCompleteEvent event) {
            }
        });
        form.setVisible(true);
        addVideoPanel.add(form);
        HTML html = new HTML("Or");
        addVideoPanel.add(html);
        videoId = new TextField<String>();
        videoId.setFieldLabel("Youtube Video Id");
        addVideoPanel.add(videoId);
        Button addVideoIdButton = new Button("Add Video by Id", new ClickHandler() {

            public void onClick(ClickEvent event) {
                addYoutubeVideoId();
            }
        });
        addVideoPanel.add(addVideoIdButton);
        layoutContainer.add(addVideoPanel);

        addNewVideoLink = new Anchor("Add new video...");
        addNewVideoLink.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                addNewVideo();

            }
        });
        layoutContainer.add(addNewVideoLink);

        initComponent(layoutContainer);
    }

    private void addYoutubeVideoId() {

        service.addYoutubeVideoById(getParentPanel().getExhibition().getId(),
                videoId.getValue(), new AsyncCallback<ExhibitionVideo>() {
                    @Override
                    public void onSuccess(ExhibitionVideo result) {
                        getParentPanel().getExhibition().getVideos().add(result);
                        refresh();
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        Log.error("Unale to add video", caught);
                        TopInfo.display("Error", "Unable to add video");
                    }
                });
        videoId.clear();
        addVideoPanel.setVisible(false);
        addNewVideoLink.setVisible(true);
    }

    protected void refresh() {
        videosPanel.clear();
        Exhibition exhibition = parent.getExhibition();
        if (exhibition != null) {
            List<ExhibitionVideo> videos = exhibition.getVideos();
            if (videos != null) {
                for (ExhibitionVideo video : videos) {
                    SWFWidget player = new SWFWidget("http://www.youtube.com/v/"
                            + video.getVideoId() + "?version=3", 400, 200);
                    videosPanel.add(player);
                }
            }
        }
    }

    private void addNewVideo() {
        service.getVideoUploadFormToken(parent.getExhibition().getId(),
                new AsyncCallback<UploadToken>() {

                    @Override
                    public void onSuccess(UploadToken result) {
                        form.setAction(result.getUrl()
                                + "?nexturl=http://localhost:8080/web/youtube_uploads/exhibition/"
                                + getParentPanel().getExhibition().getId());
                        token.setValue(result.getToken());
                        addVideoPanel.setVisible(true);
                        addNewVideoLink.setVisible(false);
                    }

                    @Override
                    public void onFailure(Throwable e) {
                        Log.error("Unable to get token", e);
                    }
                });
    }

    private ExhibitionDetailPanel getParentPanel() {
        return parent;
    }

}
